#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <pthread.h>
#include <fcntl.h>
#include <string.h>

// 共享数据结构
struct shared_data {
    pthread_mutex_t mutex;  // 互斥锁
    int counter;            // 共享计数器
};

int main() {
    const char* SHM_NAME = "/my_shm";
    const int SHM_SIZE = sizeof(struct shared_data);
    
    // 创建/打开共享内存
    int shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);
    if (shm_fd == -1) {
        perror("shm_open failed");
        exit(EXIT_FAILURE);
    }
    
    // 设置共享内存大小
    if (ftruncate(shm_fd, SHM_SIZE) == -1) {
        perror("ftruncate failed");
        exit(EXIT_FAILURE);
    }
    
    // 映射共享内存
    struct shared_data* data = mmap(NULL, SHM_SIZE, 
                                   PROT_READ | PROT_WRITE, 
                                   MAP_SHARED, shm_fd, 0);
    if (data == MAP_FAILED) {
        perror("mmap failed");
        exit(EXIT_FAILURE);
    }
    close(shm_fd);  // 文件描述符不再需要

    // 初始化互斥锁属性（进程间共享）
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    
    // 初始化互斥锁（在共享内存中）
    pthread_mutex_init(&data->mutex, &attr);
    
    //初始完互斥锁时就可以释放掉锁的属性结构了
    pthread_mutexattr_destroy(&attr);
    
    data->counter = 0;  // 初始化计数器

    // 创建子进程
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) { // 子进程
        int i;
        for (i = 0; i < 5; i++) {
            pthread_mutex_lock(&data->mutex);  // 加锁
            
            // 临界区开始
            int current = data->counter;
            printf("Child: Read counter = %d\n", current);
            sleep(1);  // 模拟处理时间
            data->counter = current + 1;
            printf("Child: Updated counter to %d\n", data->counter);
            // 临界区结束
            
            pthread_mutex_unlock(&data->mutex);  // 解锁
            sleep(1);  // 让出CPU
        }
        pthread_mutex_destroy(&data->mutex); //销毁对互斥锁的引用
        munmap(data, SHM_SIZE);
        exit(EXIT_SUCCESS);
    } 
    else { // 父进程
        int i;
        for (i = 0; i < 5; i++) {
            pthread_mutex_lock(&data->mutex);  // 加锁
            
            // 临界区开始
            int current = data->counter;
            printf("Parent: Read counter = %d\n", current);
            sleep(1);  // 模拟处理时间
            data->counter = current + 1;
            printf("Parent: Updated counter to %d\n", data->counter);
            // 临界区结束
            
            pthread_mutex_unlock(&data->mutex);  // 解锁
            sleep(1);  // 让出CPU
        }
        
        // 等待子进程结束
        wait(NULL);
        
        // 清理资源
        printf("\nFinal counter value: %d\n", data->counter);
        
        pthread_mutex_destroy(&data->mutex); //销毁对互斥锁的引用，父子进程都需要做
        //共享内存的映射，父子进程都需要解除映射
        munmap(data, SHM_SIZE);
        //这个共享内存的对象只需要创建者释放
        shm_unlink(SHM_NAME);
    }

    return EXIT_SUCCESS;
}

